package com.okex.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.okex.demo.config.WebSocketEventListener.ProductSubscriptionEvent;
import com.okex.demo.model.TickerInfo;
import com.okex.demo.service.DataPollingService;
import com.okex.demo.service.OkexApiService;
import com.okex.demo.task.AllMarketsPollingTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Date;

/**
 * WebSocket控制器
 * 处理来自客户端的WebSocket请求
 * 使用事件机制通知数据服务进行数据查询和推送
 */
@Slf4j
@Controller
public class WebSocketController {

    @Autowired
    private OkexApiService okexApiService;
    
    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    @Autowired
    private DataPollingService dataPollingService;
    
    @Autowired
    private AllMarketsPollingTask allMarketsPollingTask;
    
    /**
     * 处理行情请求
     * 客户端发送instId到/app/ticker，服务器返回对应的行情信息
     */
    @MessageMapping("/ticker")
    @SendTo("/topic/ticker")
    public TickerInfo handleTickerRequest(JSONObject request, SimpMessageHeaderAccessor headerAccessor) {
        String instId = request.getString("instId");
        if (instId == null || instId.isEmpty()) {
            log.warn("WebSocket收到无效的行情请求: instId为空");
            return new TickerInfo(); // 返回空对象
        }
        
        String sessionId = headerAccessor.getSessionId();
        log.info("WebSocket收到行情请求: {}, 会话ID: {}", instId, sessionId);
        
        try {
            // 确保产品被添加到订阅列表
            dataPollingService.addSubscription(instId);
            
            // 获取行情信息
            TickerInfo ticker = okexApiService.getTicker(instId);
            
            if (ticker != null) {
                // 确保更新时间字段被设置为当前时间，方便前端判断数据是否是最新的
                Date currentTime = new Date();
                ticker.setUpdateTime(currentTime);
                log.info("更新行情时间戳: {}, instId: {}", currentTime, instId);
                
                // 发送到特定产品的主题
                String specificTopic = "/topic/ticker/" + instId;
                log.info("推送数据到特定主题: {}", specificTopic);
                messagingTemplate.convertAndSend(specificTopic, ticker);
                
                // 同时也发送到通用主题
                messagingTemplate.convertAndSend("/topic/ticker", ticker);
                
                log.info("返回行情信息: {}", ticker.getInstId());
                return ticker;
            } else {
                log.warn("未找到行情信息: {}", instId);
                TickerInfo emptyTicker = new TickerInfo();
                emptyTicker.setInstId(instId); // 至少设置请求的instId，方便前端识别
                emptyTicker.setUpdateTime(new Date());
                return emptyTicker;
            }
        } catch (Exception e) {
            log.error("处理行情请求异常: {}", instId, e);
            TickerInfo errorTicker = new TickerInfo();
            errorTicker.setInstId(instId);
            errorTicker.setUpdateTime(new Date());
            return errorTicker;
        }
    }
    
    /**
     * 处理产品列表请求
     * 客户端发送instType，服务器返回指定类型的所有产品行情信息
     */
    @MessageMapping("/tickers")
    @SendTo("/topic/tickers")
    public List<TickerInfo> handleTickersRequest(JSONObject request) {
        String instType = request.getString("instType");
        
        log.info("WebSocket收到产品列表请求: instType={}", instType);
        
        if (instType == null || instType.isEmpty()) {
            log.warn("WebSocket收到无效的产品列表请求: instType为空");
            return Collections.emptyList();
        }
        
        try {
            // 使用AllMarketsPollingTask查询并推送所有该类型的产品行情
            allMarketsPollingTask.queryAllMarketsData(instType);
            
            // 返回空列表，因为数据已经通过AllMarketsPollingTask推送
            return Collections.emptyList();
        } catch (Exception e) {
            log.error("处理产品列表请求异常: instType={}, error={}", instType, e.getMessage(), e);
            return Collections.emptyList();
        }
    }
} 